/**
  * Author: Mei
  * Date: 2021-01-07 20:00
  * Description: 移除引用remove_reference
  *
  */
#include <iostream>
#include <type_traits>
#include <memory>
#include <typeindex>
#include <assert.h>

using namespace std;

template<class T>
struct  Construct {
    typedef typename remove_reference<T>::type U; //移除可能的引用
    Construct(): m_ptr(new U) {

    }

    typename add_lvalue_reference<U>::type //添加左值引用
    Get() const {
        *m_ptr.get() = 20;
        return *m_ptr.get();
    }

private:
    unique_ptr<U> m_ptr;
};

template<typename T>
//T* Create() {
typename remove_cv<typename remove_reference<T>::type>::type*
Create() {
    typedef typename remove_cv<typename remove_reference<T>::type>::type U;
    return new U();
}
//使用decay来简化代码
template<typename T>
typename decay<T>::type *
Create1() {
    typedef typename decay<T>::type U;
    return new U();
}

int main() {
    Construct<int> c;
    int a = c.Get();
    cout << a << endl;

    int *p = Create1<const volatile int&>(); //编译不过 需要移除引用和cv符才能获取原始的类型int

    std::type_index aa = typeid(int); //实际是调用构造函数 std::type_index(typeid(int));
    std::type_index b = aa;
    assert(aa==b); //a,b都指向同一个type_info
    //cout << typeid(int) << endl; //得到一个type_info&  不能打印
    //cout << type_index(typeid(int)) << endl;
    return 0;
}